/***************************************************************************
 *   Copyright (C) 2005 by xihe                                            *
 *   xihels@163.com                                                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef _BUDDY_MAP_H_
#define _BUDDY_MAP_H_


#include <iostream>
using namespace std;

#include <ext/hash_map>
using __gnu_cxx::hash_map;

template<typename T>
class BuddyMap {
    public:
	typedef T* value_type;
	// 所有hash_map都特化成void*, 以减少可执行文件体积
	typedef hash_map<uint32_t, void*> map_type; 
	
	~BuddyMap() { for_each(map.begin(), map.end(), DestroyElement()); }
	
	const map_type& getMap() const { return map; }
	
	value_type getElement(uint32_t id) const
	{
	    typename map_type::const_iterator iter = map.find(id);
	    if (iter != map.end())
		return static_cast<value_type>((*iter).second);
	    return NULL;
	}
	
	void insertElement(uint32_t id, value_type element)
	{
	    map.insert(typename map_type::value_type(id, element));
	}
	
	void erase() {
	    for_each(map.begin(), map.end(), DestroyElement());
	    map.erase(map.begin(), map.end());
       	}

	template<typename _Tf>
	    void forEach(_Tf f) const
	    {
		for_each(map.begin(), map.end(), Traversal<_Tf>(f));
	    }

    private:
	template <typename _Tf>
	    struct Traversal {// : public unary_function<typename map_type::value_type, void> {
		Traversal(_Tf _f) : f(_f){}
		void operator()(const typename map_type::value_type& val) 
		{
		    f(static_cast<value_type>(val.second));
		}
		_Tf f;
	    };

	struct DestroyElement : public unary_function<typename map_type::value_type, void> {
	    void operator ()(typename map_type::value_type& val)
	    {
		delete static_cast<value_type>(val.second);
	    }
	};


    private:
	map_type map;
};

#endif // _BUDDY_MAP_H_

